using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;
using System.Windows.Forms;
using System.IO;

namespace GSN
{
    public class ConfigException : Exception
    {
        public ConfigException(string msg)
            : base(msg)
        {
        }
    }

    public class NoConfigException : ConfigException
    {
        public NoConfigException(string msg)
            : base(msg)
        {
        }
    }

    static class GSNConfig
    {
        //old version
        public static string GSN_CONFIG_ICQ_UIN = "GSN/Settings/ICQ/UIN";
        public static string GSN_CONFIG_ICQ_PASSWORD = "GSN/Settings/ICQ/Password";

        // current version
        public static string GSN_CONFIG_SMS_PROVIDER = "GSN/Settings/SMS/Provider";
        //public static string GSN_CONFIG_SMS_PROVIDER_USERNAME = "GSN/Settings/SMS/Username";
        //public static string GSN_CONFIG_SMS_PROVIDER_PASSWORD = "GSN/Settings/SMS/Password";

        public static string GSN_CONFIG_INTERVAL = "GSN/Settings/Interval";
        public static string GSN_CONFIG_LOG = "GSN/Settings/Log";
        public static string GSN_CONFIG_PHONE = "GSN/Settings/Phone";
        public static string GSN_CONFIG_MAIL_USERNAME = "GSN/Settings/Mail/Username";
        public static string GSN_CONFIG_MAIL_PASSWORD = "GSN/Settings/Mail/Password";
        public static string GSN_CONFIG_MAIL_LABELS = "GSN/Settings/Mail/Labels";
        public static string GSN_CONFIG_MAIL_TYPE = "GSN/Settings/Mail/Type";
        public static string GSN_CONFIG_MAIL_SERVER = "GSN/Settings/Mail/Server";
        public static string GSN_CONFIG_MAIL_PORT = "GSN/Settings/Mail/Port";
        public static string GSN_CONFIG_PASSWORDS_ENCRYPTED = "GSN/Settings/PasswordsEncrypted";
        public static string GSN_CONFIG_AUTO_VERSION_CHECK = "GSN/Settings/AutoVersionCheck";
        public static string GSN_CONFIG_SMS_TEMPLATE = "GSN/Settings/SmsTemplate";

        private static string GSNConfigFile = "GSN.xml";

        public static void verify()
        {
            string fileName = Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GSNConfigFile;

            if (!File.Exists(fileName))
            {
                throw new NoConfigException("GSN Configuration file doesn't exist! (Filename: " + fileName + ")");
            }

            if (getConfigItem(GSN_CONFIG_PHONE) == "972540000000")
            {
                throw new NoConfigException("It seems you haven't configured GSN. Please run GSN Configuration first.");
            }
        }

        private static string getXmlPath()
        {
            return Path.GetDirectoryName(Application.ExecutablePath) + "\\" + GSNConfigFile;
        }


        // ugly, I know. @@@
        // if I'll use this for anything else than Rules, then I'll fix it.
        private static XmlDocument getConfigDocument()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(getXmlPath());
            return doc;
        }

        public static XmlNodeList getRulesNodes()
        {
            XmlDocument doc = getConfigDocument();
            return doc.SelectNodes("GSN/Settings/Rules/Rule");
        }

        public static GSN.Config.XmlPasswordNode getSmsProviderNode()
        {
            string passwordsEncrypted = getConfigItem(GSN_CONFIG_PASSWORDS_ENCRYPTED);
            bool encrypted = bool.Parse(passwordsEncrypted);
            XmlDocument doc = getConfigDocument();
            return new GSN.Config.XmlPasswordNode(doc.SelectSingleNode("GSN/Settings/SMS"), encrypted);
        }

        public static string getConfigItem(string item)
        {
            XmlDocument doc = getConfigDocument();

            XmlNode node = doc.SelectSingleNode(item);
            if (node == null)
            {
                doc = null;
                throw new ConfigException(string.Format("Item {0} not found in configuration!", item));
            }

            string value = node.InnerText;
            doc = null;

            return value;

        }

        public static Int32 getConfigItemInt(string item)
        {
            string value = getConfigItem(item);
            /*if (value == null)
                return Int32.;*/

            return Int32.Parse(value);

        }

        public static string getConfigPasswordItem(string item)
        {
            string value = getConfigItem(item);

            try
            {
                string passwordsEncrypted = getConfigItem(GSN_CONFIG_PASSWORDS_ENCRYPTED);
                if (bool.Parse(passwordsEncrypted))
                    value = CryptUtils.decrypt(value);
            }
            catch (ConfigException)
            {
                // do nothing
            }

            return value;
        }

    }
}
